package com.fjwt.gz.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fjwt.gz.core.exception.BizException;
import com.fjwt.gz.core.interfaces.UserAssetService;
import com.fjwt.gz.core.utils.SpringBeansUtil;
import com.fjwt.gz.db.entity.AssetMonthEntity;
import com.fjwt.gz.db.entity.FansEntity;
import com.fjwt.gz.db.vo.AssetMonthVO;
import com.fjwt.gz.db.vo.FansAuthVO;
import com.fjwt.gz.db.vo.FansVO;
import com.fjwt.gz.service.mapper.AssetMonthMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户月度资产等级表 服务实现类
 * </p>
 *
 * @author shiyonghao
 * @since 2025-04-09
 */
@Slf4j
@Service
public class AssetMonthService extends ServiceImpl<AssetMonthMapper, AssetMonthEntity> {

    @Value("${province.code}")
    private String provinceCode;
    @Autowired
    FansService fansService;
//    @Autowired
//    private ScoreRecordService scoreRecordService;

    private static final int PAGE_SIZE = 1000; // 每页数据量


    /**
     * 获取用户资产等级
     */
    public Map<String, Integer> getUserAssetLevel(String cstmNo, Long fansId ,String agentNo) {
        // 获取上个月最后一天
        int lastMonth = DateUtil.lastMonth().monthBaseOne();
        int year = 0;
        if (lastMonth == 12) {
            year = DateUtil.thisYear() - 1;
        } else {
            year = DateUtil.thisYear();
        }
        log.info("用户资产等级查询的年月:{}，{}", year, lastMonth);
        if (!agentNo.equals("41000122")&&!agentNo.equals("22011060")){
            Map<String,Integer> map = new HashMap<>();
            map.put("year",year);
            map.put("lastMonth",lastMonth);
            map.put("inSearch",2);
            return map;
        }
        AssetMonthEntity assetLevelEntity = this.selectAssetMonthEntity(fansId, year, lastMonth,agentNo);
        log.info("资产等级查询数据:{}", assetLevelEntity);


        if (assetLevelEntity == null) {
//          查询资产等级接口
            UserAssetService userAssetService = SpringBeansUtil.getBean(provinceCode + "UserAssetService", UserAssetService.class);
            Integer userAssetLevel = userAssetService.userAssetLevel(cstmNo,year,lastMonth);
            log.info("用户{}，资产等级实时查询数据:{}", fansId, userAssetLevel);

            //如果上个月没查出来，则进行上上个月的查询
            if (userAssetLevel == null) {
                // 获取上个月最后一天
                lastMonth = DateUtil.lastMonth().monthBaseOne();
                if (lastMonth == 1) {
                    lastMonth = 12;
                    year = DateUtil.thisYear() - 1;
                } else if (lastMonth == 2) {
                    lastMonth = 1;
                    year = DateUtil.thisYear();
                } else {
                    lastMonth = lastMonth - 2;
                    year = DateUtil.thisYear();
                }
                log.info("用户资产等级二次查询的年月:{}，{}", year, lastMonth);
                Map<String,Integer> map = new HashMap<>();
                assetLevelEntity = this.selectAssetMonthEntity(fansId, year, lastMonth, agentNo);
                if (assetLevelEntity == null){
                    userAssetLevel = userAssetService.userAssetLevel(cstmNo,year, lastMonth);
                    if (userAssetLevel == null){

                        map.put("userAssetLevel",userAssetLevel);
                        if (lastMonth + 1 > 12) {
                            year += 1;
                            lastMonth = 1;
                        } else {
                            lastMonth += 1;
                        }
                        map.put("year", year);
                        map.put("lastMonth", lastMonth);
                        map.put("inSearch",1);
                        log.info("用户暂查询异常{}，资产等级二次查询数据:{}", fansId, userAssetLevel);
                        return map;
                    }else {
                        map.put("userAssetLevel",userAssetLevel);
                        map.put("year", year);
                        map.put("lastMonth", lastMonth);
                        map.put("inSearch",1);
                        log.info("用户{}暂无上月数据，资产等级二次查询数据:{}", fansId, userAssetLevel);
                        return map;
                    }
                }
                map.put("userAssetLevel",assetLevelEntity.getLevel());
                map.put("year", year);
                map.put("lastMonth", lastMonth);
                map.put("inSearch",1);
                log.info("用户{}暂无上月数据，资产等级二次查询数据:{}", fansId, userAssetLevel);
                return map;
            }


//          写入数据库
            AssetMonthEntity assetLevel = new AssetMonthEntity();
            assetLevel.setFansId(fansId);
            assetLevel.setYear(year);
            assetLevel.setMonth(lastMonth);
            assetLevel.setLevel(userAssetLevel);
            assetLevel.setCreatedAt(DateUtil.date());
            assetLevel.setAgentNo(agentNo);
            log.info("用户资产等级写入数据库的数据:{}", assetLevel);
            save(assetLevel);

//          奖励福分
//            LambdaQueryWrapper<AssetMonthEntity> queryWrapper1 = new LambdaQueryWrapper<>();
//            queryWrapper1.eq(AssetMonthEntity::getUserId, fansId);
//            AssetMonthEntity assetLevelEntity1 = getOne(queryWrapper1);
//            if (ObjectUtils.isEmpty(assetLevelEntity1)){
//                //如果是首次查询,则进行奖励福分
//                scoreRecordService.propertyScore(fansId, Constants.POINT.PROPERTY_KEY, null);
//            }
            Map<String,Integer> map = new HashMap<>();
            map.put("userAssetLevel",userAssetLevel);
            map.put("year",year);
            map.put("lastMonth",lastMonth);
            map.put("inSearch",0);

            return map;
        } else {
            Map<String,Integer> map = new HashMap<>();
            map.put("userAssetLevel",assetLevelEntity.getLevel());
            map.put("year",year);
            map.put("lastMonth",lastMonth);
            map.put("inSearch",0);
            return map;
        }
    }

    public AssetMonthEntity selectAssetMonthEntity(Long fansId, int year, int lastMonth ,String agentNo) {
        // 是否已拉取资产等级
        LambdaQueryWrapper<AssetMonthEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AssetMonthEntity::getFansId, fansId);
        queryWrapper.eq(AssetMonthEntity::getYear, year);
        queryWrapper.eq(AssetMonthEntity::getMonth, lastMonth);
        queryWrapper.eq(AssetMonthEntity::getAgentNo, agentNo);
        AssetMonthEntity assetLevelEntity = getOne(queryWrapper);
        return assetLevelEntity;
    }


    /**
     * 处理数据库中的用户资产等级数据
     */
    public void processUserAssetLevels() {
        int page = 1;
        ExecutorService executorService = Executors.newFixedThreadPool(10); // 创建线程池

        while (true) {
            List<FansVO> assetLevelEntities = fansService.getAssetLevelsByPage(page, PAGE_SIZE, "41000122");
            if (assetLevelEntities.isEmpty()) {
                break;
            }
            // todo 柴云浩改为查询用户实名信息
            for (FansVO assetLevelEntity : assetLevelEntities) {
                if (JSONUtil.isNull(assetLevelEntity)||JSONUtil.isNull(assetLevelEntity.getCstmNo())){
                    log.info("用户未实名");
                    continue;
                }
                executorService.submit(() -> processAssetLevel(assetLevelEntity));
            }
            page++;
        }

        executorService.shutdown();
        try {
            executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        log.info("用户资产等级数据处理完成");
    }

    /**
     * 处理单个用户资产等级数据
     */
    private void processAssetLevel(FansVO assetLevelEntity) {

        Long fansId = assetLevelEntity.getFansId();
        // todo 柴云浩改为fansAuth
        String cstmNo = assetLevelEntity.getCstmNo();

        // 获取上个月最后一天
        int lastMonth = DateUtil.lastMonth().monthBaseOne();
        int year = 0;
        if (lastMonth == 12) {
            year = DateUtil.thisYear() - 1;
        } else {
            year = DateUtil.thisYear();
        }


        UserAssetService userAssetService = SpringBeansUtil.getBean(provinceCode + "UserAssetService", UserAssetService.class);
        if (cstmNo == null){
            throw new RuntimeException("用户编号不能为空");
        }
        Integer userAssetLevel = userAssetService.userAssetLevel(cstmNo,year,lastMonth);

        log.info("用户资产等级:{}", userAssetLevel);
        if (userAssetLevel != null) {
            AssetMonthEntity assetLevel = new AssetMonthEntity();
            assetLevel.setFansId(fansId);
            assetLevel.setYear(year);
            assetLevel.setMonth(lastMonth);
            assetLevel.setLevel(userAssetLevel);
            assetLevel.setAgentNo("41000122");
            assetLevel.setAgentNo1("41022445");
            assetLevel.setAgentNo2("41000122");
            assetLevel.setAgentNo3("0");
            assetLevel.setAgentNo4("0");
            assetLevel.setCreatedAt(DateUtil.date());
            log.info("用户资产等级写入数据库的数据:{}", assetLevel);
            save(assetLevel);

        }
        if (userAssetLevel == null){
            throw new RuntimeException("用户资产等级查询失败");
        }
    }

    public IPage<AssetMonthVO> selectMonth(IPage iPage, Long fansId, String locationAgentNo) {
        // 是否已拉取资产等级
        LambdaQueryWrapper<AssetMonthEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AssetMonthEntity::getFansId, fansId);
        queryWrapper.orderByDesc(AssetMonthEntity::getCreatedAt);
        queryWrapper.eq(AssetMonthEntity::getAgentNo, locationAgentNo);
        IPage<AssetMonthEntity> assetLevelEntityList = page(iPage, queryWrapper);
        //转换
        List<AssetMonthVO> voList = assetLevelEntityList.getRecords().stream().map(entity -> {
            AssetMonthVO vo = BeanUtil.copyProperties(entity, AssetMonthVO.class);
            return vo;
        }).collect(Collectors.toList());
        //封装
        IPage<AssetMonthVO> pageVo = new Page<>();
        pageVo.setRecords(voList);
        pageVo.setTotal(assetLevelEntityList.getTotal());
        pageVo.setCurrent(assetLevelEntityList.getCurrent());
        pageVo.setSize(assetLevelEntityList.getSize());
        return pageVo;
    }

}
